/*
 * Created: 2022-08-26 08:41:29
 * Author : 涛涛涛
 */
import Taro from '@tarojs/taro';
import { BaseEventOrig, ScrollViewProps } from '@tarojs/components';
import React, { createContext, useState, useCallback, useEffect } from 'react';
import { useDomHeight, useMyReducer, createReducerMapper, getDomInfo } from '@/utils';
import { GenerateActions } from '@/utils/useMyReducer';
import { IProps } from './RootPageComponent';
import { HEAD_NAVIGATION_UNEXPANDED_HEIGHT } from '@/pages/components/common/CONST';
export type HandleBodyScroll = (event: BaseEventOrig<ScrollViewProps.onScrollDetail>) => void;
export type SetHeight = (height: number) => void;
export class RootPageComponentContext {
    /** 是否允许导航展开 */
    enableExpand?: boolean;
    // /** 顶部导航栏整个内容插槽 */
    // headNavContentSlot?: React.ReactNode;
    /** 顶部导航栏右侧的功能插槽 */
    headNavContentRightSlot?: React.ReactNode;
    /** 顶部导航左侧显示 logo:点击去主页 arrow:点击返回上一页 */
    headNavLeftShow?: 'logo' | 'arrow';
    /**左边logo标题 */
    leftTitle?: string;
    /** 底部留白(单位px) */
    scrollOffsetBottom?: number;
    /** 头部固定Slot的插槽位 */
    headFixedSlot?: React.ReactNode;
    rootLayoutState: RootPageComponentHeights;
    rootLayoutDispatch: React.Dispatch<GenerateActions<typeof reducerMapper>>;
}
export const HomeContext = createContext<RootPageComponentContext>(undefined);

/** 布局的高度 */
export class RootPageComponentHeights {
    /** 顶部导航条的高度 */
    headNavHeight: typeof HEAD_NAVIGATION_UNEXPANDED_HEIGHT | 120 = 120;
    /** 顶部导航条折叠或是展开状态(冗余字段) */
    isNavExpand: boolean = true;
    /** 顶部tabs盒子的类名 */
    headFixedName: 'headFixed_dsgdsjfsh666' = 'headFixed_dsgdsjfsh666';
    /** 顶部tabs的高度 */
    headTabsHeight: number = 0;
    /** 中部滚动区域高度 */
    bodyScrollHeight: number = 0;
    /** 滚动区传入的child的高度,在整个外围scroll不进行滚动,children自身作为一个scroll-view时使用该高度 */
    bodyScrollChildHeight: number = 0;
    /** 底部footName的类样式,用来获得它的高度. */
    footName: 'myFoot_ksdfhdjh' = 'myFoot_ksdfhdjh';
    /** 底部foot的高度 */
    footHeight: number = 0;
}

/** 处理reducer的函数 */
const reducerMapper = createReducerMapper({
    initializer: null as RootPageComponentHeights,
    handleMapper: {
        //中心中间内容滚动动时触发
        figureHeadNavHeightOnBodyScroll: (state, payload: { event: BaseEventOrig<ScrollViewProps.onScrollDetail> }) => {
            const newState = { ...state };
            const { scrollTop } = payload.event.detail;
            const threshold = newState.bodyScrollHeight / 2;
            if (scrollTop - threshold > 50) {
                newState.headNavHeight = HEAD_NAVIGATION_UNEXPANDED_HEIGHT;
                newState.isNavExpand = false;
            } else if (scrollTop - threshold < -50) {
                newState.headNavHeight = 120;
                newState.isNavExpand = true;
            }
            // 如果高度实际没有发生变化,则返回原来的值.避免多次渲染
            if (state.isNavExpand === newState.isNavExpand) return state;
            return newState;
        },
        //底部高度变化,计算body滚动高度
        figureBodyScrollHeightOnMounted: (state, payload?: undefined) => {
            const newState = { ...state };
            const { windowHeight } = Taro.getSystemInfoSync();
            // 屏幕高度 - tabbar高度
            newState.bodyScrollHeight = windowHeight - state.footHeight - 2;
            return newState;
        },
        //计算滚动区传入的child的高度
        figureBodyScrollChildHeight: (state, payload: { scrollOffsetBottom: number }) => {
            const newState = { ...state };
            const { bodyScrollHeight, headNavHeight, headTabsHeight } = newState;
            newState.bodyScrollChildHeight =
                bodyScrollHeight - headNavHeight - headTabsHeight - payload.scrollOffsetBottom;
            console.log('计算children的高度', newState.bodyScrollChildHeight);
            return newState;
        },
        //页面渲染完成,获取底部tabbar的高度(可能为0)
        setFootHeightAndTabsHeightByOnMounted: (state, payload: { tabsHeight: number; footHeight: number }) => {
            const newState = { ...state };
            newState.footHeight = payload.footHeight || 0;
            newState.headTabsHeight = payload.tabsHeight || 0;
            return newState;
        },
    },
});

/** 生成高度控制的全局状态 */
export const useLayoutHeights = (props: IProps) => {
    const heights = new RootPageComponentHeights();
    if (props.enableExpand) {
        heights.headNavHeight = 120;
        heights.isNavExpand = true;
    } else {
        heights.headNavHeight = HEAD_NAVIGATION_UNEXPANDED_HEIGHT;
        heights.isNavExpand = false;
    }
    const [rootLayoutState, rootLayoutDispatch] = useMyReducer({
        initializer: heights,
        handleMapper: reducerMapper,
    });
    // 计算底部的高度
    useEffect(() => {
        setTimeout(() => {
            let p1 = getDomInfo(`.${rootLayoutState.footName}`).then((info) => {
                return info.height;
            });
            let p2 = getDomInfo(`.${rootLayoutState.headFixedName}`).then((info) => {
                return info.height;
            });
            Promise.all([p1, p2]).then(([footHeight, tabsHeight]) => {
                rootLayoutDispatch({
                    type: 'setFootHeightAndTabsHeightByOnMounted',
                    payload: {
                        footHeight,
                        tabsHeight,
                    },
                });
            });
        }, 100);
    }, [rootLayoutDispatch, rootLayoutState.footName, rootLayoutState.headFixedName]);
    /** 计算body的高度 */
    useEffect(() => {
        rootLayoutDispatch({
            type: 'figureBodyScrollHeightOnMounted',
        });
    }, [rootLayoutDispatch, rootLayoutState.footHeight]);

    /** 计算传入的children的高度 */
    useEffect(() => {
        rootLayoutDispatch({
            type: 'figureBodyScrollChildHeight',
            payload: {
                scrollOffsetBottom: props.scrollOffsetBottom,
            },
        });
    }, [
        rootLayoutDispatch,
        rootLayoutState.bodyScrollHeight,
        rootLayoutState.headNavHeight,
        rootLayoutState.headTabsHeight,
        props.scrollOffsetBottom,
    ]);
    return {
        rootLayoutState,
        rootLayoutDispatch,
    };
};
